package com.tanjun.gateway.gatewayservice.biz.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.tanjun.common.enums.EnableStatusEnum;
import com.tanjun.common.enums.RedisCacheEnum;
import com.tanjun.common.exception.BizException;
import com.tanjun.common.model.R;
import com.tanjun.common.utils.ConvertUntil;
import com.tanjun.common.utils.IdGenerator;
import com.tanjun.common.utils.UserPasswordUntil;
import com.tanjun.gateway.gatewayservice.biz.UserLoginBiz;
import com.tanjun.gateway.gatewayservice.config.SaTokenRoleAndPremissionConfig;
import com.tanjun.gateway.gatewayservice.config.StpUtilKit;
import com.tanjun.gateway.gatewayservice.request.AdminUserLoginRequest;
import com.tanjun.gateway.gatewayservice.response.CaptchaResponse;
import com.tanjun.gateway.gatewayservice.response.UserInfoResponse;
import com.tanjun.userservice.apiservice.api.AdminUserApi;
import com.tanjun.userservice.apiservice.response.adminuser.admin.AdminUserBaseResponse;
import com.tanjun.userservice.apiservice.response.adminuser.api.AdminUserResponse;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.ReactiveRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;

@Service
@Slf4j
public class UserLoginBizImpl implements UserLoginBiz {



    @Resource
    @Lazy
    private AdminUserApi adminUserApi;
    @Autowired
    private SaTokenRoleAndPremissionConfig saTokenRoleAndPremissionConfig;
    @Autowired
    @Lazy
    private ReactiveRedisTemplate<String,Object> redisTemplate;



    /**
     * 根据用户名和密码登录
     *
     * @param request 登录请求参数
     */
    @Override
    public void loginByUserName(AdminUserLoginRequest request) {
        //1.验证图形验证码是否正确
       boolean isValid= validCaptcha(request.getCaptchaKey(), request.getCaptchaCode());
        if(!isValid&&false){
            throw new BizException("验证码错误");
        }
        R<AdminUserBaseResponse> adminUser= adminUserApi.getAdminBaseInfoByKey(request.getUsername());
        log.info("userinfo:{}", JSON.toJSONString(adminUser));
        if(!adminUser.isSuccess()){
            throw new BizException("用户不存在");
        }
        if(!UserPasswordUntil.encode(request.getPassword(),adminUser.getData().getSalt()).equals(adminUser.getData().getPwd())){
            log.info("用户:{},密码错误",request.getUsername());
            throw new BizException("用户密码错误");
        }
        if(adminUser.getData().getEnabled()== EnableStatusEnum.NO){
            throw new BizException("用户已被禁用");
        }
        //sa-token登录
        StpUtilKit.adminStpLogic.login(adminUser.getData().getUserId(),request.getLoginTerminal().getCode());
        //防止修改了用户权限信息的时候登录还是缓存数据
        saTokenRoleAndPremissionConfig.clearCache(adminUser.getData().getUserId(),request.getLoginTerminal().getCode());
    }

    /**
     * 获取验证码
     * @return
     */
    @Override
    public CaptchaResponse getCaptcha() {
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(50, 20,4,20);
        String base64Captcha=lineCaptcha.getImageBase64Data();
        String captchaId= IdGenerator.generateStrId();
        String captchaCode=lineCaptcha.getCode();
        log.info("getCaptcha,captchaId:{},code:{},length:{}",captchaId,base64Captcha.length(),captchaCode);
        redisTemplate.opsForValue().set(RedisCacheEnum.CAPTCHA.getKey()+captchaId,
                captchaCode, Duration.ofMillis(RedisCacheEnum.CAPTCHA.getExpire())).block();
        return CaptchaResponse.builder()
                .captchaBase64(base64Captcha)
                .captchaKey(captchaId)
                .build();
    }

    /**
     * 获取登录的用户信息
     *
     * @return 用户基本信息
     */
    @Override
    public UserInfoResponse getLoginUserInfo() {
           R<AdminUserResponse> rAdmin= adminUserApi.getUserBaseInfo(StpUtilKit.adminStpLogic.getLoginIdAsLong());
           UserInfoResponse response= ConvertUntil.convert(rAdmin.getData(),UserInfoResponse.class);
           response.setRoles(StpUtilKit.adminStpLogic.getRoleList());
           response.setPerms(StpUtilKit.adminStpLogic.getPermissionList());
           return response;
    }

    /**
     * 退出登录
     */
    @Override
    public void logout() {
        try {
            StpUtilKit.logout();
        }
        catch (Exception e){
            log.error("退出登录异常:{}",e.getMessage(),e);
        }
    }

    /**
     * 检查验证码是否正确
     * @param captchaKey 验证码key
     * @param captchaCode 验证码值
     * @return 验证码相同，返回true
     */
    private boolean validCaptcha(@NotNull String captchaKey,
                                 @NotNull String captchaCode){
        String realCode= (String) redisTemplate.opsForValue().get(RedisCacheEnum.CAPTCHA+captchaKey).block();
        if(StrUtil.isEmpty(realCode)){
            return false;
        }
        redisTemplate.delete(RedisCacheEnum.CAPTCHA+captchaKey);
        return StrUtil.equalsIgnoreCase(captchaCode,realCode);
    }
}
